﻿using RestSharp;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using YouWei.Api.Common;
using YouWei.Api.Models;
using YouWei.Api.Models.WxMini;
using YouWei.Infrastructure.Entity;
using YouWei.Infrastructure.Service;
using YouWei.Utility;
using YouWei.Utility.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using YouWei.Infrastructure.Models;
using System.Collections.Generic;

namespace YouWei.Api.Controllers
{
    /// <summary>
    /// 微信小程序相关
    /// </summary>
    public class WxMiniController : BaseApiController
    {
        string AppId = ConfigHelper.GetAppSettingValue("weixi.miniAppId");
        string AppSecret = ConfigHelper.GetAppSettingValue("weixi.miniAppSecret");

        private AccessTokenCacheService tokenCacheService = new AccessTokenCacheService();
        private UserInfoService uService = new UserInfoService();
        private WxGroupUserService wxGroupUserSevice = new WxGroupUserService();
        private UserCardRelaService _userCardRelaService = new UserCardRelaService();

        /// <summary>
        /// 获取会话token  微信公众号开发文档
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public AccessTokenResult GetAccessToken()
        {
            AccessTokenResult result = new AccessTokenResult();
            AccessTokenCache cache = tokenCacheService.GetActiveToken(AppId);
            if (cache != null)
            {
                result.access_token = cache.AccessToken;
                return result;
            }

            var client = new RestClient("https://api.weixin.qq.com");
            var request = new RestRequest(string.Format("/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppId, AppSecret), Method.GET);
            IRestResponse response = client.Execute(request);

            if (response.Content.Contains("errcode") || response.Content.Contains("errmsg"))
            {
                //记录接口日志
                Log4netLog.Error(new Utility.Logging.ErrorLog()
                {
                    RequestUrl = string.Format("/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppId, AppSecret),
                    RequestMethod = "WxMini",
                    CreatedDate = DateTime.Now,
                    ErrorMessage = response.Content
                });

                Log4netLog.Debug(response.Content);
            }
            else
            {
                result = JsonConvert.DeserializeObject<AccessTokenResult>(response.Content);
                cache = new AccessTokenCache()
                {
                    AccessToken = result.access_token,
                    ExpireDate = DateTime.Now.AddSeconds(result.expires_in),
                    AppId = AppId,
                    CreateDate = DateTime.Now
                };
                tokenCacheService.Insert(cache);
            }
            return result;
        }

        /// <summary>
        /// 获取微信小程序授权码 openid，session_key,unionid
        /// </summary>
        /// <param name="authCode">授权码</param>
        /// <returns></returns>
        [HttpGet]
        public ResultData<WxUserDto> GetSession(string authCode)
        {
            try
            {
                var client = new RestClient("https://api.weixin.qq.com");
                var request = new RestRequest(string.Format("/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", AppId, AppSecret, authCode), Method.GET);
                IRestResponse response = client.Execute(request);

                JObject jobj = JObject.Parse(response.Content);
                JToken token = jobj.GetValue("openid");
                if (token == null)
                {
                    //记录接口日志
                    Log4netLog.Error(new Utility.Logging.ErrorLog()
                    {
                        RequestUrl = string.Format("/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", AppId, AppSecret, authCode),
                        RequestMethod = "WxMini",
                        CreatedDate = DateTime.Now,
                        ErrorMessage = response.Content
                    });

                    return ResultData<WxUserDto>.Error(response.Content);
                }
                else
                {
                    JsCode2Session data = new JsCode2Session();
                    data.openid = token.Value<string>();
                    data.session_key = jobj.GetValue("session_key").Value<string>();
                    JToken outUnionId;
                    if (jobj.TryGetValue("unionid", out outUnionId))
                    {
                        data.unionid = outUnionId.Value<string>();
                    }

                    WxUserDto userDto = uService.GetUserByOpenID(data.openid);
                    if (userDto == null)
                    {
                        userDto = new WxUserDto()
                        {
                            OpenID = data.openid,
                            UnionID = data.unionid
                        };
                    }
                    userDto.SessionKey = data.session_key;

                    if (userDto.UserID > 0)
                    {
                        userDto.CarGroupIds = wxGroupUserSevice.GetCarGroupIdByUserId(userDto.UserID);
                    }

                    //查询会员卡等级
                    if (userDto.VehicleStatus > 0)
                    {
                        userDto.CardLevel = _userCardRelaService.GetCarLevel(userDto.UserID);
                    }
                    
                    //需要总是变动，需要兼容各种情况
                    if (string.IsNullOrEmpty(userDto.UserName))
                    {
                        userDto.UserName = userDto.NickName;
                    }
                    if (string.IsNullOrEmpty(userDto.UserHead))
                    {
                        userDto.UserHead = userDto.HeadImgUrl;
                    }
                    else
                    {
                        string url = ConfigHelper.GetAppSettingValue("FileUploadUrl");
                        if (!userDto.UserHead.StartsWith("http"))
                        {
                            userDto.UserHead = url + userDto.UserHead;
                        }
                    }
                    //skCacheService.Insert(new SessionKeyCache()
                    //{
                    //    CreateDate = DateTime.Now,
                    //    OpenID = data.openid,
                    //    SessionKey = data.session_key
                    //});

                    return ResultData<WxUserDto>.Success(userDto);
                }
            }
            catch (Exception ex)
            {
                Log4netLog.Error(new Utility.Logging.ErrorLog()
                {
                    CreatedDate = DateTime.Now,
                    ClientIP = IPHelper.IPAddress,
                    ErrorMessage = ex.Message,
                    ErrorSource = ex.Source,
                    ErrorTrace = ex.StackTrace
                });
                return ResultData<WxUserDto>.Error("解析报错");
            }
        }

        /// <summary>
        /// 添加用户(微信授权获取手机号码)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ResultData<string> GetMobile(PhoneNumberModel model)
        {
            //返回值格式:{"phoneNumber":"18201032670","purePhoneNumber":"18201032670","countryCode":"86","watermark":{"timestamp":1545018096,"appid":"wxb3947f8af58393c9"}}
            string result = SecurityUtility.DecodeEncryptedData(model.SessionKey, model.encryptedData, model.iv);
            JObject jobj = JObject.Parse(result);
            JToken token = jobj.GetValue("phoneNumber");
            if (token == null)
            {
                return ResultData<string>.Error("获取电话号码失败.");
            }
            else
            {
                return ResultData<string>.Success(token.Value<string>());
            }
        }

        /// <summary>
        /// 行驶证识别
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public Task<ResultData<VehicleLicenseModel>> VehicleLicenseOcr()
        {
            ResultData<VehicleLicenseModel> rt = new ResultData<VehicleLicenseModel>();

            // 确定指定的内容是否是 MIME 多部分内容
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            //指定要将文件存入的服务器物理位置  
            string savePath = ConfigHelper.GetAppSettingValue("FileUploadPath");
            var provider = new MultipartFormDataStreamProvider(savePath);
            var task = Request.Content.ReadAsMultipartAsync(provider).
                ContinueWith(t =>
                {
                    if (t.IsFaulted || t.IsCanceled)
                    {
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
                    }
                    //获取上传文件
                    foreach (MultipartFileData file in provider.FileData)
                    {
                        //api默认保存的文件没有后缀名,需要重命名
                        FileInfo f = new FileInfo(file.LocalFileName);
                        int idx = file.Headers.ContentDisposition.FileName.LastIndexOf('.');
                        string pfx = file.Headers.ContentDisposition.FileName.Substring(idx);

                        //api的文件名,自动添加了双引号(")，此处去掉，否则会提示非法路径。  真坑
                        string newFileName = file.LocalFileName + pfx.Replace("\"", string.Empty);
                        f.MoveTo(newFileName);
                        rt = VehicleLicense(newFileName);
                    }
                    return rt;
                });
            return task;
        }

        /// <summary>
        /// 添加产品图片
        /// </summary>
        /// <returns></returns>      
        protected ResultData<VehicleLicenseModel> VehicleLicense(string filePath)
        {
            ResultData<VehicleLicenseModel> rt = new ResultData<VehicleLicenseModel>();
            //获取token
            AccessTokenResult token = GetAccessToken();
            var client = new RestClient("https://api.weixin.qq.com");
            var request = new RestRequest(string.Format("/cv/ocr/driving?type=photo&access_token={0}", token.access_token), Method.POST);
            request.AddFile("abc.png", filePath, "application/octet-stream");
            IRestResponse response = client.Execute(request);

            //记录接口日志
            Log4netLog.Info(new Utility.Logging.ActionLog()
            {
                RequestUrl = string.Format("/cv/ocr/driving?type=photo&access_token={0}", token.access_token),
                RequestMethod = "WxMini",
                CreatedDate = DateTime.Now,
                PostData = response.Content
            });

            if (response.IsSuccessful)
            {
                rt.data = JsonConvert.DeserializeObject<VehicleLicenseModel>(response.Content);
                //解析出来的发动机号和vin颠倒               
                if (rt.data.engine_num.Length > 12)
                {
                    string tmpVin = rt.data.engine_num;
                    rt.data.engine_num = rt.data.vin;
                    rt.data.vin = tmpVin;
                }
           
            }
            if (rt.data == null || string.IsNullOrEmpty(rt.data.engine_num))
            {
                rt.status = -1;
                rt.message = "行驶证识别失败";
            }
            return rt;
        }

        /// <summary>
        /// 获取分享信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ResultData<string> AddLaunchInfo(LanuchInfoModel model)
        {
            Log4netLog.Debug(JsonConvert.SerializeObject(model));
            return ResultData<string>.Success("ok");
        }
    }
}
